package cdu.sl.aichatdemo.provider;


import cdu.sl.aichatdemo.constants.CacheConstants;
import cdu.sl.aichatdemo.pojo.entity.User;
import cdu.sl.aichatdemo.pojo.entity.token.EmailCodeAuthenticationToken;
import cdu.sl.aichatdemo.service.CustomUserService;
import cdu.sl.aichatdemo.utils.CacheUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

/**
 * @Description 邮箱验证码登录认证提供者
 * @Author sunlin5@asiainfo.com
 * @Date 2025/8/21
 * @Version 1.0
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class EmailCodeAuthenticationProvider implements AuthenticationProvider {

    private final CustomUserService userService;

    private final CacheUtil cacheUtil;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 处理邮箱验证码登录的认证逻辑
        EmailCodeAuthenticationToken token = (EmailCodeAuthenticationToken) authentication;
        String email = (String) authentication.getPrincipal();
        String verificationCode = (String) authentication.getCredentials();
        // 1.根据键名 从缓存中获取验证码
        String key = CacheConstants.USER_CACHE + CacheConstants.LOGIN_VERIFICATION_CODE + email;
        String code = cacheUtil.getFormCache(key);

        // 2.验证是否匹配
        // 不匹配 抛出异常
        if (!code.equals(verificationCode)) {
            throw new BadCredentialsException("验证码不正确,校验不通过！");
        }

        // 如果匹配 查询用户信息
        User userDetails = userService.loadUserByUsername(email);
        if (userDetails == null) {
            throw new UsernameNotFoundException("没有查询到用户信息");
        }

        // 清理缓存
        cacheUtil.cleanFromCache(key);

        // 生成已认证的token
        EmailCodeAuthenticationToken authenticationToken = new EmailCodeAuthenticationToken(userDetails, userDetails.getAuthorities());
        authenticationToken.setDetails(token.getDetails());

        return authenticationToken;
    }


    @Override
    public boolean supports(Class<?> authentication) {
        return EmailCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }


}
